package com.freshmarket.freshmarket.configuration;

import com.freshmarket.freshmarket.realm.CustomRealm;
import com.freshmarket.freshmarket.utils.EncryptUtil;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.UnsupportedEncodingException;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguration {
    @Bean
    public CustomRealm customRealm() {
        CustomRealm customRealm = new CustomRealm();
        customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return customRealm;
    }

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //安全管理器注入领域对象(封装好了认证授权的方法)
        securityManager.setRealm(customRealm());
        return securityManager;
    }

    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        //用户输入的密码    数据库中的正确密码
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //设置算法名字
        hashedCredentialsMatcher.setHashAlgorithmName(EncryptUtil.ALGORITHM_NAME);
        //设置hash迭代次数
        hashedCredentialsMatcher.setHashIterations(EncryptUtil.HASH_ITERATIONS);
        return hashedCredentialsMatcher;
    }

    //实例化Shiro过滤器工厂
    @Bean
    public ShiroFilterFactoryBean shiroFilter() throws UnsupportedEncodingException {
        //实例filter工厂
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //注册securityManager(安全管理器)
        shiroFilterFactoryBean.setSecurityManager(securityManager());

        //设置Shiro过滤器规则
        //LinkedHashMap是有序hash shiro会根据添加的顺序进行拦截匹配 匹配后就执行该过滤器 不会继续向下匹配
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();

        //配置不会被拦截地址规则
        //anon:所有的url都可以不登录的情况下访问
        //authc:所有url都必须认证通过才可以访问
        //user: 所有的url都必须认证或者rememberme
        //logout: 注销
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/islogin", "anon");
        filterChainDefinitionMap.put("/login.html", "anon");
        filterChainDefinitionMap.put("/index.html", "anon");
        filterChainDefinitionMap.put("/", "anon");
        filterChainDefinitionMap.put("/index", "anon");
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/couponCenter","anon");
        filterChainDefinitionMap.put("/loginAndRegister","anon");
        filterChainDefinitionMap.put("/toProduct","anon");
        filterChainDefinitionMap.put("/freshmarket/user/islogin","anon");
        filterChainDefinitionMap.put("/selectByTypeandName","anon");
        filterChainDefinitionMap.put("/productAll","anon");
        filterChainDefinitionMap.put("/productBytype","anon");
        filterChainDefinitionMap.put("/freshmarket/user/register","anon");
        filterChainDefinitionMap.put("/freshmarket/user/login","anon");
        filterChainDefinitionMap.put("/freshmarket/product-type/getList","anon");
        filterChainDefinitionMap.put("/freshmarket/coupon/selectDirect","anon");
        filterChainDefinitionMap.put("/KillProduct","anon");
        filterChainDefinitionMap.put("/freshmarket/limited-time-offer/findProductType","anon");
        filterChainDefinitionMap.put("/freshmarket/limited-time-offer/pageKillProduct","anon");
        filterChainDefinitionMap.put("/freshmarket/limited-time-offer/address","anon");
        filterChainDefinitionMap.put("/freshmarket/limited-time-offer/user","anon");
        filterChainDefinitionMap.put("/payNotify","anon");

//        filterChainDefinitionMap.put("/**","user");
        //如果不满足上方的所有规则 则需要进行登录验证 或黑名单
        filterChainDefinitionMap.put("/**", "authc");

        //未登录时重定向的网页地址
        shiroFilterFactoryBean.setLoginUrl("/loginAndRegister");
        shiroFilterFactoryBean.setSuccessUrl("/");
        //将地址过滤规则设置到Filter工厂中
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    //用于扫描Shiro的注解和使用SpringAop来完成权限校验
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }
}
